package com.hontech.bread.device.mdb

import com.hontech.bread.utils.ExecException
import com.hontech.bread.utils.hex8
import serial.codec.CodecType
import serial.toU8

class MdbFrame(
    private val buf: ByteArray,
    private val index: Int,
    val len: Int
) {

    companion object {

        const val ACK = 0x00
    }

    fun dataLen(): Int {
        if (len == 0) {
            throw ExecException("mdb frame data is 0")
        }
        return len - 1
    }

    fun dataGet(i: Int): Int {
        if (i >= len) {
            throw ExecException("mdb frame i >= len  $i $len")
        }
        return buf[index + i].toU8()
    }

    fun isAck() = (len == 1) && (dataGet(0) == ACK)

    fun assertAck() {
        if (!isAck()) {
            throw ExecException("not ack")
        }
    }

    fun parse(offset: Int, vararg args: CodecType) {
        var i = offset
        for (arg in args) {
            if (i >= len) {
                throw ExecException("mdb frame parse out of range $i $len")
            }
            arg.decode(buf, index + i)
            i += arg.size()
        }
    }

    fun parse(vararg args: CodecType) {
        var i = 0
        for (arg in args) {
            if (i >= len) {
                throw ExecException("mdb frame parse out of range $i $len")
            }
            arg.decode(buf, index + i)
            i += arg.size()
        }
    }

    override fun toString(): String {
        val sb = StringBuilder()
        sb.append("mdb frame:")
        for (i in 0 until len) {
            sb.append(buf[index + i].toU8().hex8())
            sb.append(" ")
        }
        return sb.toString()
    }
}


